import { computed, ref, watch, nextTick } from 'vue'

import { uuid } from '../uuid'
import { catchFn } from '../common'
import { getInviteCode, getUserInfo, loginByWXCode, userCheck, userLogout } from './api'
import { log } from '../message'

/** Token */
const token = ref('')
/** 用户信息 */
const userInfo = ref<T_UserInfo>()
/** 用户信息是否完整 */
const userInfoFull = ref(false)
/** 邀请码 */
const inviteCode = ref('')
/** 用户是否已登录 */
const isLogin = computed(() => !!token.value)
/** 是否优先填写好友信息 */
const fillInFriend = ref(false)

watch(token, val => {
  uni.setStorageSync('token', val)

  // #ifdef MP-WEIXIN
  // @ts-ignore
  // enableReport && wx.uma.setUserid(val.userId)
  // #endif
})

export { token, userInfo, userInfoFull, inviteCode, isLogin, fillInFriend }

// #ifdef WEB
uni.setStorageSync('token', 'kdC89A84hH9HsjGjDjVOzg==')
// #endif

/**
 * 初始化用户信息
 * @param query 启动参数
 */
const initUserInfo = async (query: any) => {
  // #ifdef WEB
  // 微信授权页回跳
  // if (location.search) {
  //   const urlParams = new URLSearchParams(location.search)

  //   token = urlParams.get('token') || ''
  // }
  // #endif

  let inviteFrom = 'default'
  let inviteCode: string | undefined = undefined
  let inviteParam: string | undefined = undefined

  if (query.code) {
    inviteCode = query.code
    inviteFrom = 'wxshare'

    if (query.mbtiReport) {
      inviteFrom = 'mbti_report'
      inviteParam = query.mbtiReport
    }

    // 邀请填写信息
    if (query.fill) {
      fillInFriend.value = true
      console.error(fillInFriend.value)
    }
  }

  const _token = uni.getStorageSync('token')

  if (_token) token.value = _token
  else {
    // #ifdef MP-WEIXIN
    await catchFn(async () => {
      // 微信端静默登录
      const code = await new Promise<string>((resolve, reject) => {
        uni.login({
          provider: 'weixin',
          success: res => resolve(res.code),
          fail: reject,
        })
      })

      const { data } = await loginByWXCode(code, {
        inviteFrom,
        inviteCode,
        inviteParam,
      })

      token.value = data.token
    })
    // #endif
  }

  await checkUserInfo()
  await updateUserInfo()
  updateInviteCode()
}

/**
 * 校验用户信息是否完整
 */
const checkUserInfo = async () => {
  try {
    const { code } = await userCheck()

    userInfoFull.value = code === 0
  } catch (err) {
    userInfoFull.value = false
  }
}

/**
 * 更新用户信息
 */
const updateUserInfo = () => {
  if (!token.value) return Promise.resolve()

  return catchFn(
    async () => {
      const { data } = await getUserInfo()

      userInfo.value = data
      log(['用户信息', userInfo.value])
    },
    {
      disableLoading: true,
      onError() {
        clearUserInfo()

        // log(['尝试重新登录'])
        // #ifdef MP-WEIXIN
        // await initUserInfo()
        // #endif
      },
    },
  )
}

/**
 * 更新邀请码
 */
const updateInviteCode = async () => {
  const { data } = await getInviteCode()

  inviteCode.value = data.inviteCode
}

/**
 * 清空用户信息
 */
const clearUserInfo = () => {
  token.value = ''
  userInfo.value = undefined
  userInfoFull.value = false

  return nextTick()
}

/**
 * 登出
 */
const logout = async () => {
  await Promise.all([userLogout(), clearUserInfo()])

  // uni.reLaunch({ url: '/pages/main/index' })
}

export { initUserInfo, checkUserInfo, updateInviteCode, clearUserInfo, updateUserInfo, logout }

let waitFn: any = null
const GKEY = 'guest_id'

/**
 * 获取游客ID
 */
const getGuestId = async (): Promise<string> => {
  let id = uni.getStorageSync(GKEY)

  if (!id) {
    waitFn = waitFn || uuid() // 生成新的UUID
    id = await waitFn

    uni.setStorageSync(GKEY, id)
  }

  return id
}

export { getGuestId }
